import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_eve_plugin/constants/constant.dart';
import 'package:flutter_eve_plugin/plugin/actions.dart';
import 'package:flutter_eve_plugin/utils/print_util.dart';
import 'package:flutter_eve_plugin/utils/toast_util.dart';
import 'package:flutter_eve_plugin/utils/event_bus.dart';

enum HttpType { GET, POST }

class PluginEve {
  ///发送需要监听接口
  static Future<dynamic> registerMessage(
      String path, Function(dynamic data) handler) async {
    if (path == null || path.length <= 0) {
      return null;
    }
    bus.on(path, handler);
    await messageChannel.send('regPush:$path');
  }

  //监听websocket结果
  static void onEvent(Object message) {
    try {
      logDebugPrint('onEvent $message');
      var map = Map();
      var regList = [
        r'code=(\d*)',
        r'type=(\w+)',
        r'data={([\s\S]*)}',
      ];
      regList.forEach((item) {
        RegExp reg = RegExp(item);
        Iterable<Match> matches = reg.allMatches(message);
        if (matches.isNotEmpty) {
          var regData = matches?.first?.group(0);
          //=号分割可能会有误
          map[item.substring(0, 4)] = regData.split(item.substring(0, 5))[1];
        }
      });
      String type = map['type'];
      if (PluginConstant.push == type) {
        var jsonRes = json.decode(map['data']);
        bus.emit(PluginConstant.PUSH_CODE, jsonRes['code']);
      }

      logDebugPrint('receiveMessage  type $type');
      if (PluginConstant.http == type) {
        var map = Map();
        var regList = [
          r'code=(\d*)',
          r'type=(\w+)',
          r'path=(.*&)',
          r'data={([\s\S]*)}',
        ];
        regList.forEach((item) {
          RegExp reg = RegExp(item);
          Iterable<Match> matches = reg.allMatches(message);
          if (matches.isNotEmpty) {
            var regData = matches?.first?.group(0);
            //path=/bind_result& 处理最后的&
            if (item.substring(0, 4) == 'path') {
              String tmp = regData.split(item.substring(0, 5))[1];
              //=号分割可能会有误
              map[item.substring(0, 4)] = tmp.substring(0, tmp.length - 1);
            } else {
              //=号分割可能会有误
              map[item.substring(0, 4)] =
                  regData.split(item.substring(0, 5))[1];
            }
          }
        });
        logDebugPrint('receiveMessage  map');
        if (map.containsKey('type') &&
            map.containsKey('code') &&
            map.containsKey('data') &&
            map.containsKey('path') &&
            PluginConstant.http == map['type']) {
          PluginModel model = PluginModel(
              type: map['type'],
              code: map['code'],
              path: map['path'],
              data: map['data']);

          var jsonRes = json.decode(model.data);
          var httpData = httpModelFilter(model.path, jsonRes);
          bus.emit(model.path, httpData);
        }
      }
    } catch (e) {
      logDebugPrint('receiveMessage error $e');
    }
  }

  static void onError(Object error) {
    logDebugPrint('onError $error');
  }

  ///发送
  static Future<dynamic> sendMessage(dynamic message,
      {dynamic param,
      HttpType httpType = HttpType.GET,
      BuildContext context}) async {
    try {
      var tmpMessage = message;
      if (param != null) {
        var paramJsonStr = json.encode(param) ?? '';
        tmpMessage += '&' + paramJsonStr;
      }else{
        tmpMessage += '&{}';
      }
      logDebugPrint('message send - $tmpMessage');
      String reply = await messageChannel.send(
          'http:$tmpMessage&httpType:${httpType == HttpType.GET ? 'GET' : 'POST'}');
      if (reply == null || reply.isEmpty) {
        return null;
      }
      logDebugPrint('message receive - $reply');

      var map = Map();
      var regList = [r'code=(\d*)', r'type=(\w+)', r'data={([\s\S]*)}'];
      regList.forEach((item) {
        RegExp reg = RegExp(item);
        Iterable<Match> matches = reg.allMatches(reply);
        if (matches.isNotEmpty) {
          var regData = matches?.first?.group(0);
          //=号分割可能会有误
          map[item.substring(0, 4)] = regData.split(item.substring(0, 5))[1];
        }
      });

      if (map.containsKey('type') &&
          map.containsKey('code') &&
          // 有可能不存在data，例如请求武器升级 只返回type和code
          // map.containsKey('data') &&
          PluginConstant.http == map['type']) {
        PluginModel model = PluginModel(
            type: map['type'], code: map['code'], data: map['data']);
        var jsonRes = json.decode(model.data);
        logDebugPrint('message receive - ${map['type']} - ${jsonRes['code']}');
        if (jsonRes['code'] != 0) {
          if (context != null) {
            Toast.show(context, jsonRes['message']);
          }
          return null;
        }
        var httpData = httpModelFilter(message, jsonRes);
        if (httpData == null) {
          logDebugPrint('error http data');
          return null;
        } else {
          return httpData;
        }
      }
      return null;
    } catch (e) {
      logDebugPrint('error http data $e');
      return null;
    }
  }

  ///接收
  // static void receiveMessage({Function(dynamic data) handler}) {
  //   messageChannel.setMessageHandler((dynamic message) async {
  //     try {
  //       logDebugPrint(message);
  //       var map = Map();
  //       var regList = [
  //         r'code=(\d*)',
  //         r'type=(\w+)',
  //       ];
  //       regList.forEach((item) {
  //         RegExp reg = RegExp(item);
  //         Iterable<Match> matches = reg.allMatches(message);
  //         if (matches.isNotEmpty) {
  //           var regData = matches?.first?.group(0);
  //           //=号分割可能会有误
  //           map[item.substring(0, 4)] = regData.split(item.substring(0, 5))[1];
  //         }
  //       });
  //       String type = map['type'];
  //       if (PluginConstant.push == type) {
  //         //路由调转
  //         if (handler != null) {
  //           handler(map['code']);
  //         }
  //       }
  //       if (PluginConstant.http == type) {
  //         var map = Map();
  //         var regList = [
  //           r'code=(\d*)',
  //           r'type=(\w+)',
  //           r'path=(.*&)',
  //           r'data={([\s\S]*)}',
  //         ];
  //         regList.forEach((item) {
  //           RegExp reg = RegExp(item);
  //           Iterable<Match> matches = reg.allMatches(message);
  //           if (matches.isNotEmpty) {
  //             var regData = matches?.first?.group(0);
  //             //path=/bind_result& 处理最后的&
  //             if (item.substring(0, 4) == 'path') {
  //               String tmp = regData.split(item.substring(0, 5))[1];
  //               //=号分割可能会有误
  //               map[item.substring(0, 4)] = tmp.substring(0, tmp.length - 1);
  //             } else {
  //               //=号分割可能会有误
  //               map[item.substring(0, 4)] =
  //                   regData.split(item.substring(0, 5))[1];
  //             }
  //           }
  //         });
  //         if (map.containsKey('type') &&
  //             map.containsKey('code') &&
  //             map.containsKey('data') &&
  //             map.containsKey('path') &&
  //             PluginConstant.http == map['type']) {
  //           PluginModel model = PluginModel(
  //               type: map['type'],
  //               code: map['code'],
  //               path: map['path'],
  //               data: map['data']);
  //           var jsonRes = json.decode(model.data);
  //           // if (jsonRes['code'] != 0) {
  //           //   if (context != null) {
  //           //     Toast.show(context, jsonRes['message']);
  //           //   }
  //           //   return null;
  //           // }
  //           var httpData = httpModelFilter(model.path, jsonRes);
  //           bus.emit(model.path, httpData);
  //         }
  //       }
  //       return '';
  //     } catch (e) {
  //       logDebugPrint('receiveMessage error $e');
  //       return '';
  //     }
  //   });
  // }
}

class PluginModel {
  final String type;
  final String code;
  final String path;
  final String data;

  PluginModel({this.type, this.code, this.path, this.data});
}
